﻿module CPFD.Samples.NQueen

open CPFD.Monad
open CPFD.Core

//////////////////////////////////////////////////////////////////////////////////////
// N-queen
//////////////////////////////////////////////////////////////////////////////////////

let nqueen n = cp {
        let! allvars = newVars n [1..n]
        do! allDifferent allvars
        let rec diagonals vars =  
            let rec diagonals' v vrest i = cp {
                    match vrest with
                    | vr::vrs ->
                        let j = i + 1
                        do! compareBy (fun v1 v2 -> v1 <> v2 + j) v vr
                        do! compareBy (fun v1 v2 -> v1 <> v2 - j) v vr 
                        return! diagonals' v vrs j
                    | [] -> return ()
                }
            cp {
                match vars with
                | v::vs -> 
                    do! diagonals' v vs 0 
                    return! diagonals vs
                | [] -> return ()
            }
        do! diagonals allvars
        return! labelling allvars
    }

let run = runFD (nqueen 4) |> printf "nqueen: %A\n"

